quickSearch.ts ➔ init   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
import { getGlobalConfiguration, SETTINGS_websiteDisplayQuickSearch } from '../configuration/configuration';
2
import * as core from '../utils/aniwatchCore';
3
import * as helper from '../utils/helpers';
4
5
const quickSearchID = 'ea-quickSearch';
6
const quickSearchLink = 'ea-quickSearchLink';
7
8
export function init(): void {
9
    getGlobalConfiguration().getProperty(SETTINGS_websiteDisplayQuickSearch, value => {
10
        if (value) {
11
            core.runAfterLoad(() => {
12
                initSearch();
13
            }, ".*");
14
        }
15
    });
16
}
17
18
function initSearch(): void {
19
    let entry = document.createElement('li');
20
    entry.setAttribute('ng-repeat', 'item in navbar');
21
    entry.setAttribute('ng-class', '{\'anime-indicator\': item[\'@attributes\'].title==\'Anime\'}');
22
23
    let quickSearchElement = document.createElement('input');
24
    quickSearchElement.setAttribute('aria-label', 'Quick Search Input');
25
    quickSearchElement.setAttribute('ng-model-options', '{debounce: 500}');
26
    quickSearchElement.type = 'text';
27
    quickSearchElement.classList.add('ng-pristine', 'ng-valid', 'ng-empty', 'ng-touched');
28
    quickSearchElement.placeholder = 'Quick Search (Shift + F)';
29
    quickSearchElement.id = quickSearchID;
30
    // register Enter keybinding
31
    quickSearchElement.addEventListener('keypress', event => handleQuickSearch(event));
32
33
    entry.appendChild(quickSearchElement);
34
35
    // Aniwatch CSS requires the search input to be in some kind of known menu container
36
    let linkElement = document.createElement('a');
37
    linkElement.appendChild(quickSearchElement);
38
    linkElement.id = quickSearchLink;
39
    entry.appendChild(linkElement);
40
41
    let menu = document.getElementById('materialize-menu-dropdown');
42
    menu.insertAdjacentElement('beforeend', entry);
43
44
    // register focus hotkey
45
    document.addEventListener('keypress', event => handleSearchForShiftF(event));
46
47
    // additionally, the last dropdown ul has a "right: 0px" style, which has to be fixed with auto, otherwhise it will pop up in the wrong position
48
    (Array.from(menu.querySelectorAll('ul.dropdown')).slice(-1)[0] as HTMLElement).style.right = 'auto';
49
}
50
51
function handleQuickSearch(event: KeyboardEvent): void {
52
    if (event.key === 'Enter') {
53
        let quickSearchElement = document.getElementById(quickSearchID) as HTMLInputElement;
54
        let linkElement = document.getElementById(quickSearchLink) as HTMLAnchorElement;
55
56
        let url = new URL(window.location.origin)
57
        url.pathname = '/search';
58
        url.searchParams.append('q', quickSearchElement.value);
59
60
        // clicking the link; we are not setting window.location because this will trigger a complete reload of the site
61
        linkElement.href = `${url.pathname}${url.search}`;
62
        linkElement.click();
63
64
        // clean up afterwards
65
        linkElement.removeAttribute('href');
66
        quickSearchElement.value = '';
67
    }
68
}
69
70
function handleSearchForShiftF(event: KeyboardEvent): void {
71
    if (helper.isShiftPressed) {
72
        // check if some kind of input is focused already; we then prevent our hotkey
73
        if (document.activeElement instanceof HTMLInputElement || document.activeElement instanceof HTMLTextAreaElement || ((document.activeElement as HTMLElement)?.isContentEditable ?? false)) {
74
            return;
75
        }
76
77
        if (event.code === 'KeyF') {
78
            event.preventDefault();
79
            document.getElementById(quickSearchID).focus();
80
        }
81
    }
82
}